package com.spring.AOP;

import com.spring.AOP.AopAnnotation.After;
import com.spring.AOP.AopAnnotation.Around;
import com.spring.AOP.AopAnnotation.Aspect;
import com.spring.AOP.AopAnnotation.Before;
import com.spring.springInterface.BeanDefinition;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ProxyRegister {
    private boolean aspectsRegistered = false;
    private final Map<String, BeanDefinition> beanDefinitionMap ;
    private final Map<Object, Map<Class<?>, List<Method>>> aspectAdviceMap = new HashMap<>();


    public void register() {
        if (!aspectsRegistered) {
            // 遍历所有Bean定义，查找 @Aspect 注解的类
            for (Map.Entry<String, BeanDefinition> entry : beanDefinitionMap.entrySet()) {
                Class<?> beanClass = entry.getValue().getBeanClass();
                if (beanClass.isAnnotationPresent(Aspect.class)) {
                    try {
                        // 假设切面类可以直接实例化（无依赖）
                        Object aspectInstance = beanClass.getDeclaredConstructor().newInstance();
                        Map<Class<?>, List<Method>> adviceMethods = new HashMap<>();
                        // 查找通知方法
                        for (Method method : beanClass.getDeclaredMethods()) {
                            if (method.isAnnotationPresent(Before.class)) {
                                adviceMethods.computeIfAbsent(Before.class, k -> new ArrayList<>()).add(method);
                            } else if (method.isAnnotationPresent(After.class)) {
                                adviceMethods.computeIfAbsent(After.class, k -> new ArrayList<>()).add(method);
                            } else if (method.isAnnotationPresent(Around.class)) {
                                adviceMethods.computeIfAbsent(Around.class, k -> new ArrayList<>()).add(method);
                            }
                        }
                        aspectAdviceMap.put(aspectInstance, adviceMethods);
                        System.out.println("Registered aspect: " + beanClass.getName());
                    } catch (Exception e) {
                        System.err.println("Failed to instantiate aspect: " + beanClass.getName());
                        e.printStackTrace();
                    }
                }
            }
            aspectsRegistered = true;
        }
    }

    public boolean isAspectsRegistered() {
        return aspectsRegistered;
    }

    public void setAspectsRegistered(boolean aspectsRegistered) {
        this.aspectsRegistered = aspectsRegistered;
    }

    public Map<String, BeanDefinition> getBeanDefinitionMap() {
        return beanDefinitionMap;
    }

    public Map<Object, Map<Class<?>, List<Method>>> getAspectAdviceMap() {
        return aspectAdviceMap;
    }


    public ProxyRegister(Map<String, BeanDefinition> beanDefinitionMap) {
        this.beanDefinitionMap = beanDefinitionMap;
    }
}
